#ifndef __LOGGER_H__
#define __LOGGER_H__
#include "noncopyable.h"


#include <memory>
#include <spdlog/async_logger.h>
#include <spdlog/details/thread_pool.h>
#include <string>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include "spdlog/async.h"

using std::string;
using std::shared_ptr;

class Logger : noncopyable
{
public:
    static Logger &getInstance(); // 获取单例实例
    static void init(const string &log_name = "logger", // 控制台输出
              const string &filepath = "./log/log.txt", // 文件输出 
              size_t async_queue_size = 8192, // 队列容量
              size_t async_thread_count = 1,  // 线程数
              spdlog::async_overflow_policy policy =  //溢出策略
              spdlog::async_overflow_policy::block
    );

    // 核心接口
    template <typename... Args>
    static void Trace(const char *fmt, const Args &...args)
    {
        getInstance()._logger->trace(fmt, args...);
    }
    template <typename... Args>
    static void Debug(const char *fmt, const Args &...args)
    {
        getInstance()._logger->debug(fmt, args...);
    }
    template <typename... Args>
    static void Info(const char *fmt, const Args &...args)
    {
        getInstance()._logger->info(fmt, args...);
    }
    template <typename... Args>
    static void Warn(const char *fmt, const Args &...args)
    {
        getInstance()._logger->warn(fmt, args...);
    }
    template <typename... Args>
    static void Error(const char *fmt, const Args &...args)
    {
        getInstance()._logger->error(fmt, args...);
    }

    template <typename... Args>
    static void Critical(const char* fmt, const Args&... args) 
    {
        getInstance()._logger->critical(fmt, args...);
    }


    // 日志级别
    static void setLevel(spdlog::level::level_enum level);

    void flush(); //刷新异步缓冲区
    void shutdown();

private:
    Logger() = default;
    ~Logger() = default;

    shared_ptr<spdlog::logger> _logger; // 日志对象
    shared_ptr<spdlog::details::thread_pool> _threadpool;
};
#endif
